#include "common.hpp"

static const char *optString = "n:h?";

static const struct option longOpts[] = {
	{ "help", no_argument, NULL, 'h' },
	{ "name", required_argument, NULL, 'n' },
	{ 0,0,0,0 }
};

int main (int argc, char* const argv[]) {
	srand( time(NULL) + getpid() );

	// Selecciono por que puerta sale/entra la persona a generar.
	int discriminanteE = rand()%2 +16;
	int discriminanteS = rand()%2 +16;
	ipc::messages_queue_with_exceptions colaE ( ftok(BASE_NAME,discriminanteE) );
	ipc::messages_queue_with_exceptions colaS ( ftok(BASE_NAME,discriminanteS) );

	// Parametros.
	std::string nombre;

	// Variables.
	int longIndex = 0;
	int option = 0;
	bool ayuda = false;

	sMensaje pedir_entrar;
	pedir_entrar.tipo = 1;
	pedir_entrar.origen = getpid();
	pedir_entrar.data = 'E';

	sMensaje pedir_salir;
	pedir_salir.tipo = 1;
	pedir_salir.origen = getpid();
	pedir_salir.data = 'S';

	sMensaje msg;
	
	// Interpretación de parametros.
	while ( (option = getopt_long(argc,argv,optString,longOpts,&longIndex) ) != EOF ) {
		switch (option) {
			case '?':
			case 'h':
			case ':':
				ayuda = true;
				break;
			case 'n':
				nombre = optarg;
				break;
			default:
				break;
		}
	}

	if ( ayuda || nombre.empty()) {
		std::cerr << "Proceso que representa una persona que itenta utilizar el gimnasio." << std::endl;
		std::cerr << "\tUso: " << argv[0] << " [-h] <-name string>" << std::endl;
		std::cerr << "\tParametros:" << std::endl;
		std::cerr << "\t\t-h,--help:\tMostrar este mensaje de ayuda." << std::endl;
		std::cerr << "\t\t-n,--name:\tDefinir el nombre de la persona." << std::endl;

		return (nombre.empty()) ? -1 : 0;
	}

	try {
		colaE.get(PERMITS);
		colaS.get(PERMITS);
		
		logger << nombre << ": Inicio." << nl;

		//entrar.
		logger << nombre << ": Intenta entrar por la puerta " << (discriminanteE-15) << " (" << (ftok(BASE_NAME,discriminanteE)) << ")." << nl;

		colaE.send(pedir_entrar);
		msg.data = '\0';
		colaE.receive(msg,getpid());
		// msg deberia ser la respuesta de pedir_entrar.

		if (msg.data == 'E') {
			logger << nombre << ": Ingresa al gimnasio." << nl;

			//entrenar.
			logger << nombre << ": Entrenando." << nl;
			usleep ( rand()%10000 );

			//salir.
			logger << nombre << ": Intenta salir por la puerta " << (discriminanteS-15) << " (" << ftok(BASE_NAME,discriminanteS) << ")." << nl;

			colaS.send(pedir_salir);
			msg.data = '\0';
			colaS.receive(msg,getpid());
			// msg deberia ser la respuesta de pedir_salir.
			
			if (msg.data != 'S')
				logger << nombre << ": Error de logica al recibir mensaje de salida del gimnasio." << " D: " << msg.data << nl;
		} else if (msg.data == 'S') {
			logger << nombre << ": El gimnasio esta lleno." << nl;
		} else 
			logger << nombre << ": Error de logica al recibir mensaje de entrada al gimnasio." << nl;


		logger << nombre << ": Fin." << nl;
	} catch (ipc::exception& e) {
		logger << nombre << ": " << e.what() << "." << nl;
		exit(-1);
	}
	
	return 0;
}

